package com.bbcare.treat.plat.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bbcare.comm.AppException;
import com.bbcare.comm.Constants;
import com.bbcare.comm.ErrorCode;
import com.bbcare.comm.ToolUtils;
import com.bbcare.followup.plat.entity.ContentTempl;
import com.bbcare.followup.plat.entity.FollowQueue;
import com.bbcare.followup.plat.entity.Patient;
import com.bbcare.followup.plat.service.IFollowQueueService;
import com.bbcare.followup.plat.service.IPatientService;
import com.bbcare.followup.plat.store.ibatis.IConfCacheDAO;
import com.bbcare.followup.plat.store.ibatis.IContentTemplDAO;
import com.bbcare.followup.plat.store.ibatis.IPatientDAO;
import com.bbcare.treat.plat.entity.FuQueueScheme;
import com.bbcare.treat.plat.service.IOfflineTreatService;
import com.bbcare.treat.plat.service.IPatientTreatService;
import com.bbcare.treat.plat.service.IPtTaskTreatService;
import com.bbcare.treat.plat.store.ibatis.IFuQueueSchemeDAO;

/**
 * @name: 离线门诊诊疗建档相关接口实现
 * @author: DemonLee
 * @createTime: 2017.11.15
 * @description:
 * @modify:
 *
 */
@Service
public class OfflineTreatService implements IOfflineTreatService {
    private final Log logger = LogFactory.getLog(OfflineTreatService.class);

    @Autowired
    private IPtTaskTreatService ptTaskTreatService;

    @Autowired
    private IPatientTreatService patientTreatService;

    @Autowired
    private IPatientService patientSerivce;

    @Autowired
    private IFollowQueueService followQueueSerivce;

    @Autowired
    private IFuQueueSchemeDAO fuQueueSchemeDAO;

    @Autowired
    private IPatientDAO patientDao;

    @Autowired
    public IConfCacheDAO confCacheDao;

    @Autowired
    private IContentTemplDAO contentTemplDao;

    // 查询离线系统菜单接口实现
    @Override
    public Map<String, Object> listOfflineMenu(Map<String, Object> mapIn) throws Exception {
        Map<String, Object> mapOut = new HashMap<String, Object>();
        List<Map<String, Object>> outList = new ArrayList<Map<String, Object>>();
        mapOut.put("rows", outList);

        String tenantId = (String) mapIn.get("tenantId");
        String accountId = (String) mapIn.get("accountId");

        // 菜单
        Map<String, Object> rowMap = new HashMap<String, Object>();
        Map<String, Object> qryMapIn = new HashMap<String, Object>();
        qryMapIn.put("orderBySeqNo", "asc");
        qryMapIn.put("type", Constants.OFFLINE_SYSTEM_MENU_TYPE);
        qryMapIn.put("tenantId", tenantId);
        List<Map<String, Object>> retList = confCacheDao.selectBsStaticParamByTenant(qryMapIn);
        if (CollectionUtils.isNotEmpty(retList)) {
            String menuId = "";
            String templId = "";
            int b = 0;
            int bsize = retList.size();
            Map<String, Object> stMap = new HashMap<String, Object>();
            Map<String, Object> resMap = new HashMap<String, Object>();
            Map<String, Object> templMap = new HashMap<String, Object>();
            List<Map<String, Object>> menuList = new ArrayList<Map<String, Object>>();
            List<Map<String, Object>> resList = new ArrayList<Map<String, Object>>();
            Map<String, Object> inMap = new HashMap<String, Object>();
            for (b = 0; b < bsize; b++) {
                Map<String, Object> menuMap = new HashMap<String, Object>();

                stMap = retList.get(b);
                menuId = (String) stMap.get("PARAM_VALUE");
                if (StringUtils.isNotBlank(menuId)) {
                    inMap.put("queueId", stMap.get("PARAM_CODE"));
                    inMap.put("schemeBusiType", stMap.get("extend_value2"));
                    inMap.put("seqNo", Constants.QUEUE_DEFAULT_SCHEME_SEQ_NO);
                    List<FuQueueScheme> fqsList = fuQueueSchemeDAO.listByQueueId(inMap);
                    if (CollectionUtils.isEmpty(fqsList)) {
                        throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_SCHEME_NOT_EXIST, "该队列下无默认方案！");
                    }
                    List<Map<String, Object>> resourceList = new ArrayList<Map<String, Object>>();
                    menuMap.put("menuId", menuId);
                    menuMap.put("menuName", stMap.get("PARAM_NAME"));
                    menuMap.put("menuIcon", stMap.get("extend_value1"));
                    menuMap.put("queueId", stMap.get("PARAM_CODE"));
                    menuMap.put("schemeId", fqsList.get(0).getSchemeId());
                    menuMap.put("schemeBusiType", stMap.get("extend_value2"));
                    menuMap.put("resourceList", resourceList);

                    // 每个菜单下的问卷模板
                    qryMapIn.put("type", Constants.OFFLINE_SYSTEM_MENU_CONTTEMPL_TYPE);
                    qryMapIn.put("paramCode", menuId);
                    resList = confCacheDao.selectBsStaticParamByTenant(qryMapIn);
                    if (CollectionUtils.isNotEmpty(resList)) {
                        int r = 0;
                        int rsize = resList.size();
                        for (r = 0; r < rsize; r++) {
                            Map<String, Object> newResMap = new HashMap<String, Object>();
                            resMap = resList.get(r);
                            templId = (String) resMap.get("PARAM_VALUE");
                            if (StringUtils.isNotBlank(templId)) {
                                templMap.clear();
                                templMap.put("id", templId);
                                List<ContentTempl> ctList = contentTemplDao.selectTemplById(templMap);
                                if (CollectionUtils.isNotEmpty(ctList)) {
                                    newResMap.put("templId", templId);
                                    newResMap.put("templName", resMap.get("PARAM_NAME"));
                                    newResMap.put("taskId", resMap.get("extend_value1"));
                                    newResMap.put("templVersion", ctList.get(0).getNewVersion());

                                    resourceList.add(newResMap);
                                }
                            }
                        }
                    }

                    menuList.add(menuMap);
                }
            }
            rowMap.put("menuList", menuList);

            // 租户信息
            qryMapIn.clear();
            qryMapIn.put("id", tenantId);
            List<Map<String, Object>> infoList = confCacheDao.listTenantByCondition(qryMapIn);
            if (CollectionUtils.isNotEmpty(infoList)) {
                Map<String, Object> tenantMap = infoList.get(0);
                rowMap.put("tenantIcon", tenantMap.get("icon"));
                rowMap.put("tenantId", tenantId);
                rowMap.put("tenantName", tenantMap.get("name"));
                rowMap.put("tenantRootGroupId", tenantMap.get("root_group_id"));
                rowMap.put("tenantType", tenantMap.get("type"));

                // 账号-应用关联信息
                qryMapIn.clear();
                qryMapIn.put("tenantId", tenantId);
                qryMapIn.put("accountId", accountId);
                infoList = confCacheDao.listAccAppByCondition(qryMapIn);
                if (CollectionUtils.isNotEmpty(infoList)) {
                    Map<String, Object> accAppMap = infoList.get(0);
                    rowMap.put("id", accAppMap.get("id"));
                    rowMap.put("accountType", accAppMap.get("account_type"));
                    rowMap.put("accountRelationId", accAppMap.get("account_relation_id"));
                    rowMap.put("roleId", accAppMap.get("role_id"));
                    rowMap.put("status", accAppMap.get("status"));
                }

                outList.add(rowMap);
            }

            logger.debug("rowMap==" + rowMap);
        }
        mapOut.put("total", outList.size());

        return mapOut;
    }

    // 离线任务内容提交
    @Override
    @Transactional
    public Map<String, Object> commitOfflinePatientQueue(Map<String, Object> mapIn) throws Exception {
        Map<String, Object> mapOut = new HashMap<String, Object>();
        Map<String, Object> paramMap = new HashMap<String, Object>(mapIn);
        Integer schemeBusiType = (Integer) paramMap.get("schemeBusiType");
        Map<String, Object> quesMap = ToolUtils.typeCast(paramMap.get("contentData"));

        // 队列信息
        Map<String, Object> mapQry = new HashMap<String, Object>();
        mapQry.put("id", paramMap.get("queueId"));
        FollowQueue queue = followQueueSerivce.getQueueDetailByQueueId(mapQry);
        if (null == queue) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_QUEUE_NOT_EXIST, "无此队列信息！"));
        }
        String queueUserType = queue.getQueueUsertype();
        paramMap.put("queueUserType", queueUserType);

        // 离线任务无患者id和患者队列实例id
        Map<String, Object> userQueue = this.dealOfflinePatientQueue(paramMap);
        paramMap.put("opRecordDealFlag", userQueue.get("dealFlag"));// 若为1表示先建档了，操作记录表不需要再插入
        paramMap.put("ptSchemeId", userQueue.get("ptSchemeId"));
        paramMap.put("userId", userQueue.get("userId"));
        // 剔除建档的几个基本字段
        quesMap.remove(Constants.QUESTION_ID_FOR_PHONENO);
        quesMap.remove(Constants.QUESTION_ID_FOR_PATIENTNAME);
        quesMap.remove(Constants.QUESTION_ID_FOR_GENDER);
        quesMap.remove(Constants.QUESTION_ID_FOR_BIRTHDAY);
        quesMap.remove(Constants.QUESTION_ID_FOR_EXPECTEDDAY);
        quesMap.remove(Constants.QUESTION_ID_FOR_PREGNANCYDAY);
        quesMap.remove(Constants.QUESTION_ID_FOR_PREGNANCT_NO);
        quesMap.remove(Constants.QUESTION_ID_FOR_INPATIENT_NO);
        paramMap.put("contentData", quesMap);

        if (schemeBusiType == Constants.SCHEME_BUSI_TYPE_0) {
            patientSerivce.modTaskContentData(paramMap);
        } else if (schemeBusiType == Constants.SCHEME_BUSI_TYPE_1) {
            mapOut = ptTaskTreatService.submitTaskFunciton(paramMap);
        } else {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "暂不支持此方案业务类型！");
        }

        return mapOut;
    }

    // 离线患者信息获取（查询或建档）
    public Map<String, Object> dealOfflinePatientQueue(Map<String, Object> mapIn) throws Exception {
        Map<String, Object> mapOut = new HashMap<String, Object>();
        Map<String, Object> paramMap = new HashMap<String, Object>(mapIn);
        Map<String, Object> quesMap = ToolUtils.typeCast(paramMap.get("contentData"));

        String tenantId = (String) paramMap.get("tenantId");
        String queueId = (String) paramMap.get("queueId");
        String phoneNo = (String) quesMap.get(Constants.QUESTION_ID_FOR_PHONENO);
        String userName = (String) quesMap.get(Constants.QUESTION_ID_FOR_PATIENTNAME);
        String hisNo1 = (String) quesMap.get(Constants.QUESTION_ID_FOR_PREGNANCT_NO);
        String hisNo2 = (String) quesMap.get(Constants.QUESTION_ID_FOR_INPATIENT_NO);

        String userId = "";
        String ptSchemeId = "";
        int dealFlag = 0;
        List<Map<String, Object>> ptList = null;
        // 根据手机号、姓名和队列id查询是否已经有该患者（并且加入到了该队列）
        Map<String, Object> qryMapOut = new HashMap<String, Object>();
        Map<String, Object> qryMapIn = new HashMap<String, Object>();
        qryMapIn.put("phoneNo", phoneNo);
        qryMapIn.put("tenantId", tenantId);
        qryMapIn.put("userNameFull", userName);
        qryMapIn.put("queueId", queueId);
        qryMapIn.put("userStatus", Constants.PATIENT_QUEUESCHEME_USER_STATUS_NOMAL);// 队列中正常状态下的用户
        qryMapIn.put("hisNo1", hisNo1);
        qryMapIn.put("hisNo2", hisNo2);
        // 手机号、诊疗卡号和住院号都为空的话，则新建档
        if (StringUtils.isNotBlank(phoneNo) || StringUtils.isNotBlank(hisNo1) || StringUtils.isNotBlank(hisNo2)) {
            ptList = patientDao.selectPtSchemeByCondition(qryMapIn);
        }
        if (CollectionUtils.isEmpty(ptList)) {
            // 无此患者，需要先建档
            qryMapOut = this.dealOfflineAddNewPatient(paramMap);
            ptSchemeId = (String) qryMapOut.get("ptSchemeId");
            userId = (String) qryMapOut.get("patientId");
            dealFlag = 1;
            logger.info("---no user-queue, savePatientArchives...userId==" + userId + ", ptSchemeId==" + ptSchemeId);
        } else {
            // 有此患者，且加入了该队列
            qryMapOut = ptList.get(0);
            ptSchemeId = (String) qryMapOut.get("ptSchemeId");
            userId = (String) qryMapOut.get("id");
            dealFlag = 0;
            logger.info("---user-queue exists...userId==" + userId + ", ptSchemeId==" + ptSchemeId);
        }
        mapOut.put("ptSchemeId", ptSchemeId);
        mapOut.put("userId", userId);
        mapOut.put("dealFlag", dealFlag);

        return mapOut;
    }

    // 离线患者建档
    public Map<String, Object> dealOfflineAddNewPatient(Map<String, Object> mapIn) throws Exception {
        Map<String, Object> mapOut = new HashMap<String, Object>();
        Map<String, Object> paramMap = new HashMap<String, Object>(mapIn);
        Map<String, Object> quesMap = ToolUtils.typeCast(paramMap.get("contentData"));

        // 拼装建档入参
        String queueUserType = (String) paramMap.get("queueUserType");
        Integer schemeBusiType = (Integer) paramMap.get("schemeBusiType");
        String birthday = (String) quesMap.get(Constants.QUESTION_ID_FOR_BIRTHDAY);
        String patientName = (String) quesMap.get(Constants.QUESTION_ID_FOR_PATIENTNAME);
        String authorName = (String) paramMap.get("authorName");
        String authorId = (String) paramMap.get("authorId");
        String currTime = (String) paramMap.get("updateTime");
        String expectedDay = (String) quesMap.get(Constants.QUESTION_ID_FOR_EXPECTEDDAY);
        Integer pregnancyDay = (Integer) quesMap.get(Constants.QUESTION_ID_FOR_PREGNANCYDAY);
        if ((null == pregnancyDay || pregnancyDay <= 0) && StringUtils.isNotBlank(expectedDay)) {
            pregnancyDay = ToolUtils.calPrenDayByBirthAndExpect(birthday, expectedDay);
        }

        String gender = (String) quesMap.get(Constants.QUESTION_ID_FOR_GENDER);
        String userType = "";
        if (Constants.QUEUE_USER_TYPE_BABY.equals(queueUserType)) {
            // 宝宝
            userType = Constants.PTUSER_PATIENT_USER_TYPE_BABY;
            if (null == pregnancyDay || pregnancyDay <= 0) {
                pregnancyDay = Constants.PATIENT_NORMAL_PREGNANT_DAY;// 孕周默认280
                expectedDay = birthday;
            }
        } else if (Constants.QUEUE_USER_TYPE_PARTURIENT.equals(queueUserType)) {
            // 孕产妇（母亲）
            userType = Constants.PTUSER_PATIENT_USER_TYPE_PARTURIENT;
            gender = Constants.GENDER_FOR_FEMALE;
        } else {
            // 其他
            userType = Constants.PTUSER_PATIENT_USER_TYPE_OTHER;
        }
        if (null == pregnancyDay || pregnancyDay <= 0) {
            pregnancyDay = null;
        }
        if (StringUtils.isBlank(gender)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "性别不能为空！"));
        }
        gender = gender.trim();
        // 转换性别
        if (Constants.GENDER_ALIAS_FOR_MALE.equals(gender)) {
            gender = Constants.GENDER_FOR_MALE;
        } else if (Constants.GENDER_ALIAS_FOR_FEMALE.equals(gender)) {
            gender = Constants.GENDER_FOR_FEMALE;
        } else if (!Constants.GENDER_FOR_MALE.equals(gender) && !Constants.GENDER_FOR_FEMALE.equals(gender)) {
            gender = Constants.GENDER_FOR_MALE;
        }

        // 方案id
        String queueId = (String) paramMap.get("queueId");
        Map<String, Object> qryMapIn = new HashMap<String, Object>();
        qryMapIn.put("queueId", queueId);
        qryMapIn.put("schemeBusiType", schemeBusiType);
        qryMapIn.put("seqNo", Constants.QUEUE_DEFAULT_SCHEME_SEQ_NO);
        List<FuQueueScheme> fqsList = fuQueueSchemeDAO.listByQueueId(qryMapIn);
        if (CollectionUtils.isEmpty(fqsList)) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_SCHEME_NOT_EXIST, "该队列下无默认方案！");
        }
        List<Map<String, Object>> schemeList = new ArrayList<Map<String, Object>>();
        Map<String, Object> schemeMap = new HashMap<String, Object>();
        schemeMap.put("schemeBusiType", schemeBusiType);
        schemeMap.put("schemeId", fqsList.get(0).getSchemeId());
        schemeList.add(schemeMap);

        Map<String, Object> servParamMap = new HashMap<String, Object>();
        servParamMap.put("schemeList", schemeList);
        servParamMap.put("deliveryDate", quesMap.get(Constants.QUESTION_ID_FOR_LAST_DELIVERY_DATE));
        servParamMap.put("lastMenstruationDate", quesMap.get(Constants.QUESTION_ID_FOR_LAST_MENSTRUATION_DATE));
        String firstChkPregWeek = (String) quesMap.get(Constants.QUESTION_ID_FOR_PREGNANCY_FIRST_WEEK);
        if (StringUtils.isNotBlank(firstChkPregWeek)) {
            servParamMap.put("firstChkPregWeek", Integer.parseInt(firstChkPregWeek));
        }
        Patient pt = new Patient();
        pt.setPregnancyDay(pregnancyDay);
        pt.setUserName(patientName);
        pt.setPhoneNo((String) quesMap.get(Constants.QUESTION_ID_FOR_PHONENO));
        pt.setFirstName(patientName.substring(0, 1));
        pt.setCreateTime(currTime);
        pt.setUpdateTime(currTime);
        pt.setCreateAuthor(authorId);
        pt.setBirthday(birthday);
        pt.setExpectedDay(expectedDay);
        pt.setGender(gender);
        pt.setUserType(userType);
        pt.setSourceType(Constants.OP_TYPE_DOOR);

        Map<String, Object> quesMapNew = new HashMap<String, Object>();
        quesMapNew.put(Constants.QUESTION_ID_FOR_PHONENO, quesMap.get(Constants.QUESTION_ID_FOR_PHONENO));
        quesMapNew.put(Constants.QUESTION_ID_FOR_PATIENTNAME, quesMap.get(Constants.QUESTION_ID_FOR_PATIENTNAME));
        quesMapNew.put(Constants.QUESTION_ID_FOR_GENDER, quesMap.get(Constants.QUESTION_ID_FOR_GENDER));
        quesMapNew.put(Constants.QUESTION_ID_FOR_BIRTHDAY, quesMap.get(Constants.QUESTION_ID_FOR_BIRTHDAY));

        String preNo = (String) quesMap.get(Constants.QUESTION_ID_FOR_PREGNANCT_NO);
        if (StringUtils.isNotBlank(preNo)) {
            quesMapNew.put(Constants.QUESTION_ID_FOR_PREGNANCT_NO, preNo);
        }
        String inptNo = (String) quesMap.get(Constants.QUESTION_ID_FOR_INPATIENT_NO);
        if (StringUtils.isNotBlank(inptNo)) {
            quesMapNew.put(Constants.QUESTION_ID_FOR_INPATIENT_NO, inptNo);
        }
        if (StringUtils.isNotBlank(expectedDay)) {
            quesMapNew.put(Constants.QUESTION_ID_FOR_EXPECTEDDAY, expectedDay);
        }
        if (null != pregnancyDay && pregnancyDay > 0) {
            quesMapNew.put(Constants.QUESTION_ID_FOR_PREGNANCYDAY, "" + pregnancyDay);
        }

        servParamMap.put("patient", pt);
        servParamMap.put("authorName", authorName);
        servParamMap.put("deptId", paramMap.get("deptId"));
        servParamMap.put("queueId", queueId);
        servParamMap.put("updateTime", currTime);
        servParamMap.put("authorId", authorId);
        servParamMap.put("updateAccept", paramMap.get("updateAccept"));
        servParamMap.put("tenantId", paramMap.get("tenantId"));
        servParamMap.put("opCode", Constants.OP_CODE_1000);
        servParamMap.put("opNote", "离线系统下【" + authorName + "】医生给【" + patientName + "】患者建档");
        servParamMap.put("opType", Constants.OP_TYPE_DOOR);
        servParamMap.put("contentData", quesMapNew);

        logger.info("--dealOfflineAddNewPatient.savePatientArchives---arg==" + servParamMap);
        mapOut = patientTreatService.savePatientArchives(servParamMap);

        return mapOut;
    }
}
